package com.hxk.juc.thread.volatileLearn;

import java.util.concurrent.TimeUnit;

/**
 *volatile是java轻量级的线程同步机制
 * 他有3大特性：
 *    1、保证数据在线程间的可见性
 *    2、不保证数据在线程间的原子性
 *    3、保证数据在线程间的有序性（禁止指令重排）
 * 及volatile的实现了JMM的特性2大特性（可见性和有序性），
 *  JMM（java Memory Model）java内存模型
 *      JMM三大特性：
 *          1、可见性
 *          2、原子性
 *          3、有序性
 * 本case主要是volatile【可见性】特性的演示案例
 *      使用A线程对资源中的变量num进行修改，修改后写回主内存后，要让main线程很快可见A线程改动了num的值
 */
public class VolatileCase1 {

    public static void main(String[] args) {

        MyData myData = new MyData();

        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+"\t 进入准备修改num，当前值为："+myData.num);
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            myData.numTo50();
            System.out.println(Thread.currentThread().getName()+"\t 修改完毕，值为："+myData.num);
            },"A").start();

        //循环判断num的值，如果不加volatile，while在当前程序相当于while (ture)
        while (myData.num == 0){

        }

        System.out.println(Thread.currentThread().getName()+"\t 检测到num的值被了，值为："+myData.num);

    }
}

/**
 * 资源类
 */
class MyData{
    /***
     * 当不加volatile时，线程A修改了num后主线程main时不可见num的值
     */
    volatile int num = 0;

    public void numTo50(){
        this.num = 50;
    }
}

